<!--
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-02-10 13:30:47
 * @Description  : 章节选择器
-->

<template>
  <n-tree-select
    size="small"
    class="my-chapter-select"
    v-model:value="value"
    filterable
    placeholder="选择章节"
    :options="options"
    :multiple="multiple"
    :render-label="renderLabel"
    :render-tag="multiple ? renderMultipleSelectTag : renderTagSinger"
    @update:value="handleValueChange"
    :allow-checking-not-loaded="true"
  ></n-tree-select>
</template>

<script setup lang="ts">
import type { VNodeChild } from 'vue'
import type { SelectRenderTag, TreeSelectOption } from 'naive-ui'
import useChapterStore from '@/stores/modules/chapter'
import type { IndexObj } from '@/types/commom'
import { flattenArrayByChildren } from '@/utils'
import { renderTag, renderDepLabel } from '@/utils/commonBusiness'

const chapterStore = useChapterStore()

// 默认选中的章节ID数组
const props = withDefaults(
  defineProps<{
    defaultChapterIds?: string[]
    defaultChapterId?: string
    multiple?: boolean
    rootChapter?: IndexObj
  }>(),
  {
    defaultChapters: () => [],
    multiple: true,
    rootChapter: () => ({
      id: '1',
      pid: '-1'
    })
  }
)

const emits = defineEmits<{
  (e: 'changeValue', value: string | string[], chapterInfo: IndexObj[]): void
}>()

// 将选中项交给当前组件进行管理（？ 为什么不直接绑定到当前select选择器呢？）
// 希望它功能更加强大，1-defaultChapters可选，需要默认值时，可传递
// 2-不需要默认值时，value发送变化会触发事件，发给父组件
watch(
  props,
  (newValue) => {
    if (newValue.multiple) {
      if (newValue.defaultChapterIds) {
        value.value = newValue.defaultChapterIds || []
      }
    } else {
      if (newValue.defaultChapterId) {
        value.value = newValue.defaultChapterId || ''
      }
    }
  },
  {
    deep: true
  }
)

const value = ref<string | string[]>([])

const options = ref<IndexObj[]>([])

const flatOptions = computed(() => {
  return flattenArrayByChildren(options.value)
})

const renderMultipleSelectTag: SelectRenderTag = ({ option, handleClose }) => {
  return renderTag(option, handleClose, () => renderDepLabel(option))
}

const renderTagSinger: SelectRenderTag = ({ option, handleClose }) => {
  return renderDepLabel(option)
}

const renderLabel = (info: {
  option: TreeSelectOption
  checked: boolean
  selected: boolean
}): VNodeChild => {
  return renderDepLabel(info.option)
}

// 加载根章节数组
const initOptions = async () => {
  if (!chapterStore.fullChapterList.length) {
    await chapterStore.getFullChapterList()
  }

  options.value = chapterStore.treeFullChapterList

  props.defaultChapterIds && (value.value = props.defaultChapterIds)

  props.defaultChapterId && (value.value = props.defaultChapterId)
}

// 章节选择项发送改变，触发事件
const handleValueChange = (value: string | string[], option: IndexObj) => {
  // console.log(value, option, 'chapter-select')

  let newValue: string[] | string = []
  if (typeof value === 'string') {
    newValue = option ? option.id : ''
  } else {
    newValue = option
      .filter((v: IndexObj) => !!v)
      .map((item: IndexObj) => item.id)
  }

  // 这里只返回了选中的章节数组ID，如果想返回更多的信息，可以使用第二参数
  const chaptersInfo = flatOptions.value.filter((item) => {
    return newValue.includes(item.id)
  })
  emits('changeValue', newValue, chaptersInfo)
}

// 只有叶子节点才可以添加章节
// 只有叶子节点才可添加题目

onMounted(() => {
  initOptions()
})
</script>

<style scoped lang="scss">
.my-chapter-select {
  :deep(.n-base-selection-placeholder__inner) {
    font-size: 13px;
  }
}
</style>
